# -*- coding: utf-8 -*-
"""
@Time: 2025/2/17 14:56
@File: get_product.py
@IDE: PyCharm
@Auth: Kendrick.Kc.Guan
@Email: 509556985@qq.com
@Version: 1.0
"""

import urllib.request
import traceback
from multiprocessing import Process
from django.conf import settings
from django.http import JsonResponse
from django.forms.models import model_to_dict
from rest_framework.response import Response
from datetime import datetime, timedelta
from rest_framework.views import APIView
from apps.ipo.kc_views.jst_open_api import JuShuiTanOpenPlatformApi
from apps.ipo.models import JSTOpen, JSTOpenImage


class RefreshDataProduct:

    def __init__(self):
        self.thread_data()

    def thread_data(self):

        datas = list()
        obj = JSTOpen.objects.last()
        last_data = model_to_dict(obj)
        jst_client = JuShuiTanOpenPlatformApi(
            url = last_data['urls'],
            app_key = last_data['app_key'],
            app_secret = last_data['app_secret']
        )

        res_datetime_list = self.datetime_to_list(last_data['data_start_time'])

        """ 获取数据 """
        for rdate in res_datetime_list:
            try:
                biz = {
                    'modified_begin': rdate['start'], 'modified_end': rdate['end']
                    ,'page_index': 1 ,'page_size': 50
                }
                result = jst_client.call('/open/sku/query', biz)

                if result['code'] == 0:
                    if result['data']['has_next'] and result['data']['page_count'] > 0:
                        print(f"页数{result['data']['page_count']}")
                        for i in range(1, result['data']['page_count'] + 1):
                            biz['page_index'] = i
                            result = jst_client.call('/open/sku/query', biz)
                            if result['code'] == 0:
                                print(f'获取{rdate["start"]}到{rdate["end"]}数据[{i}], 共{len(result["data"]["datas"])}条.')
                                for rd in result['data']['datas']:
                                    datas.append({'sku_id': rd['sku_id'], 'sku_name': rd['properties_value'], 'pic_url': rd['pic']})
                            else:
                                print(f'请求失败: {result}')
                    else:
                        print(f'获取{rdate["start"]}到{rdate["end"]}数据[无], 共{len(result["data"]["datas"])}条. {result}')
                        for rd in result['data']['datas']:
                            datas.append({'sku_id': rd['sku_id'], 'sku_name': rd['properties_value'], 'pic_url': rd['pic']})
                else:
                    print(f'请求失败: {result}')
            except:
                print(f'请求聚水潭开放平台异常: {traceback.format_exc()}')

        """ 保存图片到本地"""
        print(f"正在下载图片...")
        for i in range(len(datas)):
            res_down = self.download_image(datas[i]['pic_url'], datas[i]['sku_id'])
            datas[i]['down'] = res_down

        """ 存储到数据库  """
        new_datas = [item for item in datas if item['down']]
        self.save_product(new_datas)

        """ 更新获取数据的开始时间 """
        obj.data_start_time = datetime.now()
        obj.save()

        return JsonResponse({'data': datas})

    @staticmethod
    def datetime_to_list(start_datetime):
        """
        将日期转换为间隔1天的日期列表
        :param start_datetime:
        :return: datetime list
        """

        # 将字符串转换为datetime对象
        end_datetime = datetime.now()

        # 不足一天直接返回
        if (end_datetime - start_datetime).days == 0:
            return [{'end': end_datetime.strftime('%Y-%m-%d %H:%M:%S'),
                       'start': start_datetime.strftime('%Y-%m-%d %H:%M:%S')}]

        # 生成间隔7天的N个起始时间
        num_weeks = (end_datetime - start_datetime).days // 7
        result = [{'end': (end_datetime - timedelta(days=i * 7)).strftime('%Y-%m-%d %H:%M:%S'),
                   'start': (end_datetime - timedelta(days=(i + 1) * 7)).strftime('%Y-%m-%d %H:%M:%S')}
                  for i in range(num_weeks)]

        # 处理剩余不满足7天的时间
        if (end_datetime - start_datetime).days % 7 != 0:
            result.append({'end': (end_datetime - timedelta(days=num_weeks * 7)).strftime('%Y-%m-%d %H:%M:%S'),
                           'start': start_datetime.strftime('%Y-%m-%d %H:%M:%S')})
        return result

    # 将图片数据下载到本地并记录
    @staticmethod
    def download_image(image_url: str, image_number: str):
        try:
            if image_url:
                if image_url[:4] != 'http':
                    image_url = 'https:' + image_url
                # print(f"商品编码{image_number}下载图片: {image_url}")
                output_path = f'{image_number}.jpg'
                safe_output_path = output_path.encode('utf-8').decode('utf-8')
                urllib.request.urlretrieve(str(image_url).split('?')[0], f'{settings.MEDIA_ROOT}/{safe_output_path}')
                return output_path
            return None

        except:
            print(f"商品编码{image_number}下载图片失败: {image_url} \n {traceback.format_exc()}")

    # 将记录的数据上传到数据库
    @staticmethod
    def save_product(data):
        print(f"保存商品数据")
        for item in data:
            if item['down']:
                try:
                    JSTOpenImage.objects.get_or_create(
                        number=item['sku_id'],
                        name=item['sku_name'],
                        paths=f"{settings.MEDIA_URL}{item['down']}"
                    )
                except:
                    print(f"商品编码{item['sku_id']}保存失败: {item['down']} \n {traceback.format_exc()}")


class GetProduct(APIView):

    def post(self, request):
        """
        定时任务
        从外部链接获取数据
        :param request:
        :return:
        """
        p = Process(target=RefreshDataProduct)
        p.start()
        return Response({'code': 200 , 'msg': '后台更新数据中', 'data': {}})





